// 封装axios网络请求对象

import axios, {type AxiosInstance, type AxiosResponse, type InternalAxiosRequestConfig,type AxiosRequestConfig} from "axios";
import {ElMessage} from "element-plus";

// 定义axios配置项：后端请求地址+超时时间
const config = {
    baseURL: "http://localhost:8089",
    // baseURL: '/api', //这个和vite.config.ts中proxy中的  ’/api'呼应
    timeout: 10000,
}

// 定义返回值类型
export interface Result<T = any>{
    code: number;
    msg: string;
    data: T;
}

// Http类对象
class Http{
    // 定义axios实例
    private instance: AxiosInstance;

    // 构造器
    constructor(configs:AxiosRequestConfig) {
        //初始化实例化
        this.instance = axios.create(configs)
        //拦截器
        this.interceptors()
    }

    // 拦截器
    private interceptors(){
        // 请求：携带token
        this.instance.interceptors.request.use((config:InternalAxiosRequestConfig) => {
            let token = ''
            if (token && config){
                config.headers['token'] = token
            }
            return config
        }),(error:any) => { //异常
            error.data = {}
            error.data.msg = '服务器异常，请联系管理员'
            return error
        }

        // 响应
        this.instance.interceptors.response.use((res:AxiosResponse) => {
            if (res.data.code === 200){
                return res.data
            }else {
                ElMessage.error(res.data.msg || '接口报错！')
                //抛异常
                return Promise.reject(res.data.msg || '接口报错！')
            }
        }),(error:any) => { //异常1
            error.data = {}
            if (error && error.response){
                switch (error.response.status) {
                    case 400:
                        error.data.msg = '错误请求'
                        ElMessage.error(error.data.msg)
                        break
                    case 401:
                        error.data.msg = '未授权，请重新登录'
                        ElMessage.error(error.data.msg)
                        break
                    case 403:
                        error.data.msg = '拒绝访问'
                        ElMessage.error(error.data.msg)
                        break
                    case 404:
                        error.data.msg = '接口请求失败'
                        ElMessage.error(error.data.msg)
                        break
                    case 405:
                        error.data.msg = '请求方法不允许'
                        ElMessage.error(error.data.msg)
                        break
                    case 408:
                        error.data.msg = '接口请求超时'
                        ElMessage.error(error.data.msg)
                        break
                    case 500:
                        error.data.msg = '后端程序报错'
                        ElMessage.error(error.data.msg)
                        break
                    case 501:
                        error.data.msg = '网络未实现'
                        ElMessage.error(error.data.msg)
                        break
                    case 502:
                        error.data.msg = '网络错误'
                        ElMessage.error(error.data.msg)
                        break
                    case 503:
                        error.data.msg = '服务不可用'
                        ElMessage.error(error.data.msg)
                        break
                    case 504:
                        error.data.msg = '网络超时'
                        ElMessage.error(error.data.msg)
                        break
                    case 505:
                        error.data.msg = 'http版本不支持该请求'
                        ElMessage.error(error.data.msg)
                        break
                    default:
                        error.data.msg = `连接错误${error.response.status}`
                        ElMessage.error(error.data.msg)
                }
            }else {
                error.data.msg = '服务器连接失败'
                ElMessage.error(error.data.msg)
            }
            return Promise.reject(error)
        }
    }

    //封装请求方式,restful风格
    //1.post
    post<T = Result>(url:string,data?:object):Promise<T>{
        return this.instance.post(url, data)
    }
    //2.put
    put<T = Result>(url:string,data?:object):Promise<T>{
        return this.instance.put(url, data)
    }
    //3.get
    get<T = Result>(url:string,params?:object):Promise<T>{
        return this.instance.get(url, {params})
    }
    //4.delete
    delete<T = Result>(url:string):Promise<T>{
        return this.instance.delete(url)
    }
    //5.图片上传
    upload<T = Result>(url:string,params?:object):Promise<T>{
        return this.instance.post(url, params,{
            headers:{
                'Content-Type': 'multipart/form-data'
            }
        })
    }
}

export default new Http(config)